import React, { useMemo, useEffect, useImperativeHandle, useState, useRef } from "react";
import { useDispatch, useSelector } from "react-redux";
import useUrlState from '@ahooksjs/use-url-state';
import moment from 'moment';
import CustomTable from "@/components/CustomTable";
import SeniorSearch from '@/components/SeniorSearch';
import ajax from "@/common/ajax";
import { QueryTableProps, UrlState } from './types'

const DEFAULT_PAGE_NUM = 1;
const DEFAULT_PAGE_SIZE = 10;


const useQueryTable = ({
    columns = [],
    requestUrl = '',
    multipleButtons,
    responseDatafield = 'data',
    rightButtons,
    carryParams = {},
    pagingInServer,
    rowSelectKey, // 多选的自定义selectkey，不传时table组件内默认取id
    handleDataSource = (value) => { return value?.content },
    handleRequestSearchParams = (value) => value,
    leftCustomComp = null,
    defaultFormNum = 2,
    reqExtraParams = {},
    ...Props
  }: QueryTableProps) => {
    const dispatch = useDispatch();
    const [dataObj, setDataObj] = useState([]);
    const [loading, setLoading] = useState(false);
    const [searchConfig, setSearchConfig] = useState([]);
    const [searchConfigFieldsList, setSearchConfigFieldsList] = useState([]);
    const CustomTableRef = useRef();
    const [isFirstColumns, setIsFirstColumns] = useState(true);
    const [isFirstUrlState, setIsFirstUrlState] = useState(true);
    const [isFirstGetData, setIsFirstGetData] = useState(true);
    const [urlState, setUrlState] = useUrlState<UrlState>({}, { navigateMode: 'replace' });
  
    // 请求成功之后的响应处理函数
    const respSuccFn = (res) => {
      if (res) {
        const aDataSource = pagingInServer ? res : res.dataSource;
        if (aDataSource?.length === 0 && urlState?.pageNum > 1) {
          handleResetFn(urlState.pageNum - 1);
          return;
        }

        let dataSource = handleDataSource(aDataSource);
  
        if ((multipleButtons || []).filter((i) => i.disabled !== false)?.length > 0) {
          // disabled === false 是不依赖多选操作的按钮，在判断多选相关事项时忽略它
          // table组件内默认取id，没有id时会出现错误
          dataSource = dataSource.map((item) => {
            if (item?.id) return item;
            item.id = item?.[rowSelectKey];
            return item;
          });
        }
        setDataObj({
          dataSource,
          total: pagingInServer ? res.totalSize : null,
        });
      }
    };
    const getSearchParams = () => {
      // 通过搜索字段过滤url得到搜索参数对象
      const searchParams = {};
      searchConfigFieldsList.map((item) => {
        if (urlState[item]) {
          searchParams[item] = urlState[item];
        }
      });
      return searchParams;
    };

    const getTableData = (sendRequest = true, num) => {
      setLoading(true);
      const searchParams = getSearchParams();
      const {
        pageNum = DEFAULT_PAGE_NUM,
        pageSize = DEFAULT_PAGE_SIZE,
        isDesc,
        orderBy,
        state,
      } = urlState;
      const tableParams = { pageNum: num || pageNum, pageSize, isDesc, orderBy, state, ...reqExtraParams };
      if (pagingInServer) {
        const params = {
          ...tableParams,
          ...handleRequestSearchParams({ ...searchParams }),
          ...carryParams,
        };
        const res = ajax.post(requestUrl, params);
        res.then((data) => {
          setLoading(false);
          respSuccFn(data);
        });
      } else {
        // 前端分页的请求
        // dispatch({
        //   type: 'api/getCustomTableListNoPaging',
        //   sendRequest,
        //   url: requestUrl,
        //   payload: carryParams,
        //   searchParams: handleRequestSearchParams({ ...searchParams }),
        //   responseDatafield,
        //   handleDataSource,
        //   defaultSorter: true,
        // })
      }
    };
  
    // 从columns 分离出高级搜索的配置项
    const getSearchConfig = () =>
      columns
        .map((item) => {
          if (item.searchConfig) {
            return {
              field: item.searchConfig.searchField || item.dataIndex,
              label: item.searchConfig.title || item.title,
              ...item.searchConfig,
            };
          }
        })
        .filter((item) => item !== undefined);
  
    // 设置高级搜索的配置函数
    const setSearchConfigFn = () => {
      const searchConfiglist = getSearchConfig();
      setSearchConfig(searchConfiglist);
      setSearchConfigFieldsList(searchConfiglist.map((item) => item.field));
    };
  
    // // 从对象中过滤掉要去掉的属性
    // const objFilterFields = (obj, filterFields = []) => {
    //   const filteredObj = {};
    //   for (const i in obj) {
    //     if (obj.hasOwnProperty(i) && !filterFields.includes(i)) {
    //       filteredObj[i] = obj[i];
    //     }
    //   }
    //   return filteredObj;
    // };
    useEffect(() => {
      setIsFirstColumns(false);
      setSearchConfigFn();
    }, [columns]);
  
    useEffect(() => {
      setIsFirstUrlState(false);
    }, [urlState]);
    useMemo(() => {
      // 是否是colmuns和urlstate获取完成之后的第一次data请求
      const bFirstGetData = !isFirstColumns && !isFirstUrlState && isFirstGetData;
  
      // 是否是colmuns和urlstate获取完成并已经发送了第一次data请求
      const isRerender = !isFirstColumns && !isFirstUrlState && !isFirstGetData;
      if (bFirstGetData) {
        getTableData();
        setIsFirstGetData(false);
      } else if (isRerender) {
        getTableData(false);
      }
    }, [urlState, isFirstUrlState, isFirstColumns]);
  
    const refreshTable = (sendRequest = true) => {
      // sendRequest是否发送请求
      if (sendRequest) {
        getTableData();
      } else {
        // 刷新列表某一项
        setDataObj({
          ...dataObj,
          dataSource: handleDataSource(dataObj.dataSource),
        });
      }
  
      CustomTableRef?.current?.changeTableParams();
    };
  
    // 暴露清除多选按钮的事件
    const clearSelectedKeys = () => {
      CustomTableRef.current.clearSelectedKeys();
    };
  
    const handleSearchFn = (values = {}) => {
      /**
       * 对比更新后的values和url之前的是否值时一致的
       * 一致的话重新发请求，不一致的话因为会修改url从而引起刷新，所以不需要主动刷新
       */
      let isSame = true;
      if (!urlState?.pageSize) {
        isSame = false;
      }
      for (const [key, value] of Object.entries(values)) {
        if (urlState[key] !== value && (!!value || !!urlState[key])) {
          isSame = false;
          break;
        }
      }
      if (isSame && pagingInServer) refreshTable();
      const { pageNum, pageSize } = urlState;
      // 执行表格更新函数
      setUrlState({
        ...values,
        pageNum: isSame ? pageNum : DEFAULT_PAGE_NUM,
        pageSize: isSame ? pageSize : DEFAULT_PAGE_SIZE,
      });
  
      CustomTableRef.current.changeTableParams({
        pageNum: isSame ? pageNum : DEFAULT_PAGE_NUM,
        pageSize: isSame ? pageSize : DEFAULT_PAGE_SIZE,
      });
    };
    const handleResetFn = () => {
      // 记录需要重置的变量
      const resetFormValues = {};
      searchConfig.map((item) => {
        resetFormValues[item.field] = null;
      });
      setUrlState({
        ...resetFormValues,
        pageNum: DEFAULT_PAGE_NUM,
        pageSize: DEFAULT_PAGE_SIZE,
      });
      CustomTableRef.current.changeTableParams({
        pageNum: DEFAULT_PAGE_NUM,
        pageSize: DEFAULT_PAGE_SIZE,
      });
    };
    const onTableChange = (params) => {
      const { current, pageSize, isDesc, orderBy, filters } = params;
      setUrlState({
        pageNum: current,
        pageSize,
        isDesc,
        orderBy,
        ...filters,
      });
    };
    const oColumns = useMemo(() => {
      return columns.filter((i) => !i.searchOnly).map((item) => {
        if (item?.timeFormat) {
          item.render = (text) => moment(text).format(item?.timeFormat);
        }
        if (item?.enumMapping) {
          item.render = (text) => item?.enumMapping[text] ?? '--';
        }
        if (item?.actionGroup) {
          item.render = (text, record) => {
            return (
              <>
              {
                item?.actionGroup.map((actionItem) => {
                  return (
                    <>
                     <a onClick={() => actionItem?.onClick(text, record)}>{actionItem?.title}</a>
                     <br />
                    </>
                  )
                })
              }
              </>
            )
          };
        }
        return item;
      })
    }, [columns])

    const tableJSX = (
      <div style={{ marginBottom: '16px' }}>
        {(searchConfig.length > 0 || rightButtons?.length) && (
          <SeniorSearch
            searchConfig={searchConfig}
            rightButtons={rightButtons}
            handleSearchFn={handleSearchFn}
            handleResetFn={handleResetFn}
            initValue={urlState}
            leftCustomComp={leftCustomComp}
            defaultFormNum={defaultFormNum}
          />
        )}
        <CustomTable
          columns={oColumns}
          dataObj={dataObj}
          loading={loading}
          initValue={urlState}
          onTableChange={onTableChange}
          multipleButtons={multipleButtons}
          ref={CustomTableRef}
          {...Props}
        />
      </div>
    );
    return [tableJSX, refreshTable, clearSelectedKeys];
  };
  
  const QueryTable = React.forwardRef((props, ref) => {
    const [table, refresh, clearRefSelectedKeys] = useQueryTable(props);
    useImperativeHandle(ref, () => ({
      refreshTable: () => {
        refresh();
      },
      clearSelectedKeys: () => {
        clearRefSelectedKeys();
      },
    }));
    return table;
  });
  
  export { useQueryTable, QueryTable };